package com.cn.config.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.io.Serializable;

@Getter
@Setter
public abstract class Result implements Serializable {

    private String code;

    /**
     * @param code 错误码
     */
    protected Result(String code) {
        this.code = code;
    }

    /**
     * @return 返回spring mvc需要的类
     */
    public abstract ResponseEntity<Result> ResponseEntity();

    /**
     * 快速构建一个成功地响应类
     *
     * @param code 错误码
     * @param data 需要返回的数据
     * @param <T>  data的类型
     * @return 返回响应类
     */
    public static <T> Result success(String code, T data) {
        return new SuccessResult<>(code, data);
    }

    /**
     * 快速构建一个成功地响应类, 错误码默认为0
     *
     * @param data 需要返回的数据
     * @param <T>  data的类型
     * @return 返回响应类
     */
    public static <T> Result success(T data) {
        return success("0", data);
    }

    /**
     * 快速构建一个成功地没有数据的响应类
     *
     * @return 返回响应类
     */
    public static Result success() {
        return success(null);
    }

    /**
     * 快速构建一个失败地响应类, 错误码默认为2
     *
     * @param msg 错误信息
     * @return 返回响应类
     */
    public static Result failure(String msg) {
        return new FailureResult("2", msg);
    }

    /**
     * 快速构建一个失败地响应类,
     *
     * @param code 错误码
     * @param msg  错误信息
     * @return 返回响应类
     */
    public static Result failure(String code, String msg) {
        return new FailureResult(code, msg);
    }

    @Getter
    @Setter
    private static class SuccessResult<T> extends Result {

        private T data;

        private SuccessResult(String code, T data) {
            super(code);
            this.data = data;
        }

        @Override
        public ResponseEntity<Result> ResponseEntity() {
            return new ResponseEntity<>(this, HttpStatus.OK);
        }
    }

    @Getter
    @Setter
    private static class FailureResult extends Result {

        private String msg;

        private FailureResult(String code, String msg) {
            super(code);
            this.msg = msg;
        }

        @Override
        public ResponseEntity<Result> ResponseEntity() {
            return new ResponseEntity<>(this, HttpStatus.OK);
        }
    }

}